package c_ch11.weightedGraph;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

//无向有权图；
public class WeightedGraph_try implements Cloneable{

	private int V, E;
	private HashMap<Integer, Integer>[]	adj;
	
	public WeightedGraph_try(String graph) {
		
		try( Scanner sc = new Scanner(new FileInputStream(new File(graph))) ){
			
			V = sc.nextInt();
			if(V < 0) throw new IllegalArgumentException("V is illegal;");
			E = sc.nextInt();
			if(E < 0) throw new IllegalArgumentException("E is illegal;");
			
			adj = new HashMap[V];
			for (int i = 0; i < adj.length; i++) {
				adj[i] = new HashMap<>();
			}

			for (int i = 0; i < E; i++) {
				int a = sc.nextInt();
				validateVertex(a);
				int b = sc.nextInt();
				validateVertex(b);
				int c = sc.nextInt();
				
				if(a == b) throw new IllegalArgumentException("發現自環邊！");
				if(adj[a].containsKey(b)) continue;
				
				adj[a].put(b, c); 
				adj[b].put(a, c);
				
			}
			
			
		}catch (FileNotFoundException e) { //如果抛出去，上层还得处理，接口调起来就很麻烦；除非上层有什么特殊处理，如果没有的话就在发生处catch是最省事的；
			e.printStackTrace();
		}
		
		
	}

	public void validateVertex(int vertex) {
		if(vertex < 0 || vertex >= V)
			throw new IllegalArgumentException(String.format("index %d is illegal", vertex));
	}

	public int getV() {
		return V;
	}

	public int getE() {
		return E;
	}
	
	public Iterable<Integer> adj(int v) {
		validateVertex(v);
		return adj[v].keySet();
	}

	public int weight(int v, int edge) {
		validateVertex(v);
		validateVertex(edge);
		return adj[v].get(edge);
	}
	
	public int degree(int v) {
		validateVertex(v);
		return adj[v].size();
	}
	
	public void removeEdge(int v, int edge) {
		validateVertex(v);
		validateVertex(edge);
		if( adj[v].remove(edge) != null ) { //现在仍然是无向图，有权无向图；
			adj[edge].remove(v);
			E --;
		}
	}
	
	@Override
	public Object clone() {  // 如果不实现clonable接口，CloneNotSupportedException就会抛出；
		try {
			WeightedGraph_try cloned  = (WeightedGraph_try) super.clone();  //super.clone()调用的是native方法 返回一个当前对象的克隆对象(当前类实现了Clonable接口);

			cloned.adj = new HashMap[V];   //对浅克隆进行修改，引用类型的指针指向新空间；
		
			for (int i = 0; i < adj.length; i++) {
				cloned.adj[i] = new HashMap<>();  //对指针开辟空间
				for (Map.Entry<Integer, Integer> entry : adj[i].entrySet()) {
					cloned.adj[i].put(entry.getKey(), entry.getValue());
				}
			}
		
			return cloned;
		
		}catch (CloneNotSupportedException e) {
			e.printStackTrace();
		}
		
		return null;
	}
	
    @Override
    public String toString(){
        StringBuilder sb = new StringBuilder();

        sb.append(String.format("V = %d, E = %d\n", V, E));
        for(int v = 0; v < V; v ++){
            sb.append(String.format("%d : ", v));
            for(Map.Entry<Integer, Integer> entry: adj[v].entrySet())
                sb.append(String.format("(%d: %d) ", entry.getKey(), entry.getValue()));
            sb.append('\n');
        }
        return sb.toString();
    }
    
    public static void main(String[] args){

        WeightedGraph_try g = new WeightedGraph_try("wg.txt");
        System.out.println(g);
        
        g.removeEdge(0, 3);
        System.out.println(g);
        
        WeightedGraph_try cloned = (WeightedGraph_try) g.clone();
        cloned.removeEdge(0, 1);
        cloned.removeEdge(0, 5);
        
        System.out.println(cloned);
        System.out.println(g);
    }
    
	
}
